import asyncio
import concurrent.futures
import os
import threading
import time
from asyncio import AbstractEventLoop


# def ping(url):
#     print("阻塞函数开始运行，当前的线程ID为：",threading.current_thread(),"进程ID为：", os.getpid(),"\n")
#     time.sleep(2)
#     print("ping输出 %s\n" %  url)
#     print("阻塞函数运行结束，当前的线程ID为：",threading.current_thread(),"\n")
#
# def start_thread_loop(loop):
#     asyncio.set_event_loop(loop)
#     loop.run_forever()
#
#
# if __name__ == '__main__':
#     print("In main thread ", threading.current_thread())
#     loop = asyncio.get_event_loop()
#
#     t = threading.Thread(target=start_thread_loop, args=(loop,))
#     t.start()
#     threadingExecutor = concurrent.futures.ThreadPoolExecutor(2)
#     processExecutor = concurrent.futures.ProcessPoolExecutor()
#
#     loop.run_in_executor(threadingExecutor, ping, "www.baidu.com")
#     loop.run_in_executor(threadingExecutor, ping, "www.qq.com")
#     loop.run_in_executor(threadingExecutor, ping, "www.sina.com")
#     print("主线程不会阻塞")


# async def asyncfunc1():
#     print("Suspending func1")
#     await asyncio.sleep(1)
#     print("func func1 ", threading.current_thread())
#     print("Resuming func1")
#     return "func1"
#
# async def asyncfunc2():
#     print("Suspending func2")
#     await asyncio.sleep(1)
#     print("func func2 ",threading.current_thread())
#     print("Resuming func2")
#     return "func2"
#
# def start_thread_loop(loop):
#     asyncio.set_event_loop(loop)
#     loop.run_forever()
#
# if __name__ == "__main__":
#     print("In main thread ", threading.current_thread())
#     loop = asyncio.get_event_loop()
#     t = threading.Thread(target=start_thread_loop, args=(loop,))
#     t.start()
#     asyncio.run_coroutine_threadsafe(asyncfunc1(), loop)
#     asyncio.run_coroutine_threadsafe(asyncfunc1(), loop)
#     asyncio.run_coroutine_threadsafe(asyncfunc2(), loop)
#     asyncio.run_coroutine_threadsafe(asyncfunc2(), loop)
#     print("主线程不会阻塞")
#


def ping(url):
    print("阻塞函数开始运行,当前的线程ID为：",threading.current_thread(),"进程ID为：",os.getpid())
    time.sleep(4)
    os.system("ping %s" % url)
    print("阻塞函数运行结束,当前的线程ID为：",threading.current_thread())
    return url


async def asyncfunc1():
    print("Suspending func1")
    await asyncio.sleep(1)
    print("func func1 ", threading.current_thread())
    print("Resuming func1")
    return "func1"

async def asyncfunc2():
    print("Suspending func2")
    await asyncio.sleep(2)
    print("func func2 ",threading.current_thread())
    print("Resuming func2")
    return "func2"

def start_thread_loop(loop):
    print("loop线程ID为",threading.current_thread())
    asyncio.set_event_loop(loop)
    loop.run_forever()

def callbackfunc(task):
    print("task 运行结束，它们的结果是：", task.result())
    # loop.stop()


async def main():
    t1 = time.time()
    # 使用loop.create_task创建task对象，返回asyncio.tasks.Task对象
    task1 = loop.create_task(asyncfunc1())
    task2 = loop.create_task(asyncfunc2())

    # 使用asyncio.run_coroutine_threadsafe 返回的是concurrent.futures._base.Future 对象
    # 注意这个对象没有 __await__方法，所以不能对其使用await 但是可以给它添加回调add_done_callback
    task3 = asyncio.run_coroutine_threadsafe(asyncfunc1(), loop)
    task4 = asyncio.run_coroutine_threadsafe(asyncfunc2(), loop)

    # 使用loop.run_in_executor 创建阻塞的任务，返回asyncio.futures.Future对象
    task5 = loop.run_in_executor(None, ping, "www.baidu.com")
    task6 = loop.run_in_executor(None, ping, "www.qq.com")

    # 使用asyncio.ensure_future 创建任务对象
    task7 = asyncio.ensure_future(asyncfunc1())
    task8 = asyncio.ensure_future(asyncfunc2())

    task1.add_done_callback(callbackfunc)
    task2.add_done_callback(callbackfunc)
    task3.add_done_callback(callbackfunc)
    task4.add_done_callback(callbackfunc)
    task5.add_done_callback(callbackfunc)
    task6.add_done_callback(callbackfunc)
    task7.add_done_callback(callbackfunc)
    task8.add_done_callback(callbackfunc)

    res = await asyncio.gather(task1, task2,task7, task8)
    print(res)
    t2 = time.time()
    print(t2-t1)

def shutdown(loop:AbstractEventLoop):
    loop.stop()

async def main2():
    result = await asyncio.gather(asyncfunc1(), asyncfunc2(),)
    print(result)

if __name__ == "__main__":
    print("In main thread ", threading.current_thread())
    loop = asyncio.get_event_loop()
    loop2 = asyncio.new_event_loop()

    t = threading.Thread(target=start_thread_loop, args=(loop,))
    t.start()
    asyncio.run_coroutine_threadsafe(main(), loop)
    print("主线程不会阻塞")

